<?php

namespace app\index\service;

use app\common\ConfigBase;
use app\common\model\ToolModel;
use app\index\model\PurchasemanageModel;

class PurchasemanageService
{
    static public $typeStr = [
        1 => '自动'
        , 2 => '手动'
    ];

    /**
     *上传采购明细处理
     * @param $data
     * @return array
     * @author xiejunyu
     */
    static public function uploadHandle($data)
    {
        $msg = [];//提示信息
        $sku = [];
        $res = [];
        foreach ($data as $k => &$v) {
            $line = $k + 2;
            if (empty($v[0])) {
                $msg[] = "第{$line}行sku不能为空";
            }
            if (in_array($v[0], $sku)) {
                $msg[] = "第{$line}行存在重复sku";
            }
            if (!preg_match("/^[1-9][0-9]*$/", $v[1])) {
                $msg[] = "第{$line}行数量必须为正整数";
            }
            if (!preg_match("/(^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$)|(^[1-9]\d*$)/", $v[2])) {
                $msg[] = "第{$line}行单价{$v[2]}必须为数字";
            }
            $v[0] = strtoupper($v[0]);
            $sku[] = $v[0];
        }
        if (!empty($msg)) {
            return returnArr(500, $msg);
        }
        $skuInfo = \app\common\service\SkuService::getBatchInfoBySku($sku, ['cnname']);
        if (empty($skuInfo)) {
            $msg[] = "SKU信息获取失败!";
        }
        foreach ($data as $k2 => $v2) {
            if (empty($skuInfo[$v2[0]])) {
                $msg[] = "sku:{$v2[0]}在基础资料不存在";
                continue;
            }
            $temp = [];
            $temp['sku'] = $v2[0];
            $temp['sku_name'] = $skuInfo[$temp['sku']]['cnname'] ?? '';
            $temp['quantity'] = $v2[1];
            $temp['unit_price'] = $v2[2];
            $temp['money'] = $temp['quantity'] * $temp['unit_price'];
            $res[] = $temp;
        }
        if (!empty($msg)) {
            return returnArr(500, $msg);
        }
        return returnArr(1, '', $res);
    }

    //页面手动生成或编辑
    static public function createHandle($param)
    {
        ToolModel::startTrans();
        try {
            $res = self::create($param);
            if ($res['code'] == 1) {
                ToolModel::commit();
            } else {
                ToolModel::rollback();
            }
            return $res;
        } catch (\Exception $e) {
            ToolModel::rollback();
            trace($e->getMessage(), 'error');
            return returnArr(600, '失败' . $e->getMessage());
        }
    }

    /**
     *创建或编辑采购单
     * @param $param
     * @return array
     * @author xiejunyu
     */
    static public function create($param)
    {
        if (empty($param['supplier_company_id']) || empty($param['purchase_company_id']) || empty($param['arrival_date'])) {
            return returnArr(500, '参数不全');
        }
        $data = [];
        $data['purchase_company_id'] = $param['purchase_company_id'];
        $data['receipt_warehouse_id'] = $param['receipt_warehouse_id'] ?? 0;
        $data['supplier_company_id'] = $param['supplier_company_id'];
        $data['ship_warehouse_id'] = $param['ship_warehouse_id'] ?? 0;
        $data['arrival_date'] = $param['arrival_date'];
        $data['remark'] = $param['remark'] ?? '';
        $data['bs_code'] = $param['bs_code'] ?? '';
        $data['type'] = $param['type'] ?? 2;//2手动1自动
        $data['status'] = $param['status'] ?? 10;//10未完成20完成
        $data['ctime'] = TIME;
        $data['user'] = CN_NAME;

        $dataDetail = [];
        $msg = [];

        $getCompany = ConfigBase::getCompany();
        $getWarehouse = ConfigBase::getWarehouse();
        if (empty($getCompany[$data['purchase_company_id']])) {
            $msg[] = "采购公司不存在或被禁用!";
        }
        if (empty($getCompany[$data['supplier_company_id']])) {
            $msg[] = "供应商公司不存在或被禁用!";
        }
        //手动
        if ($data['type'] == 2) {
            if (empty($param['receipt_warehouse_id'])) {
                $msg[] = "收货仓库不能为空";
            } else {
                if (empty($getWarehouse[$data['receipt_warehouse_id']])) {
                    $msg[] = "收货仓库不存在或被禁用!";
                }
                $receipt_warehouse_type = ToolModel::getValue('base_warehouse', ['id' => $data['receipt_warehouse_id']], 'type');
                if ($receipt_warehouse_type != 2) {
                    $msg[] = "收仓库不是国家仓!";
                }
            }
            $sku = array_column($param['list'], 'sku');
            $skuInfo = \app\common\service\SkuService::getBatchInfoBySku($sku, ['cnname']);
            if (empty($skuInfo)) {
                $msg[] = "SKU信息获取失败!";
            }
        }
        if (!empty($msg)) {
            return returnArr(500, $msg);
        }
        if ($param['id']) {
            $id = $param['id'];
            $data['id'] = $id;
            $dataDetailOld = ToolModel::select('purchase_order_detail', ['po_id' => $param['id']], '*', '', 'id');
            ToolModel::dbInsertOrUpdate('purchase_order', [$data]);
        } else {
            $id = ToolModel::insertData($data, 'purchase_order');
            ToolModel::updateData(['id' => $id], ['code' => 'CG' . $id], 'purchase_order');
        }
        if (!$id) {
            return returnArr(500, '生成采购单错误!');
        }
        $sku = [];
        $money = 0;
        foreach ($param['list'] as $v) {
            if (empty($v)) {
                continue;
            }
            $temp = [];
            $temp['sku'] = $v['sku'];
            $temp['sku_name'] = $v['sku_name'] ?? '';
            $temp['quantity'] = $v['quantity'] ?? 0;
            $temp['unit_price'] = $v['unit_price'] ?? 0;
            $temp['money'] = $v['money'] ?? 0;
            $temp['po_id'] = $id;
            $temp['ctime'] = TIME;
            if ($data['type'] == 2) {
                if (empty($skuInfo[$v['sku']])) {
                    $msg[] = "sku:{$temp['sku']}在基础资料不存在";
                    continue;
                }
                $temp['sku_name'] = $skuInfo[$temp['sku']]['cnname'] ?? '';
            }
            if (in_array($v['sku'], $sku)) {
                $msg[] = "sku:{$temp['sku']}存在重复sku";
                continue;
            }
            if (!preg_match("/^[1-9][0-9]*$/", $v['quantity'])) {
                $msg[] = "sku:{$temp['sku']}数量{$v['quantity']}必须为正整数";
                continue;
            }
            if (!preg_match("/(^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$)|(^[1-9]\d*$)/", $v['unit_price'])) {
                $msg[] = "sku:{$temp['sku']}单价{$v['unit_price']}必须为数字";
                continue;
            }
            $temp['money'] = bcmul($temp['unit_price'], $temp['quantity'], 5);
            $money = bcadd($money, $temp['money'], 5);
            if (!empty($param['id'])) {
                if (empty($dataDetailOld[$v['id']]) || $dataDetailOld[$v['id']]['sku'] != $v['sku']) {
                    $msg[] = "sku:{$temp['sku']}在明细中不存在";
                }
            }
            $sku[] = $v['sku'];
            unset($temp['LAY_TABLE_INDEX']);
            $dataDetail[] = $temp;
        }
        if (!empty($msg)) {
            return returnArr(500, $msg);
        }
        ToolModel::dbInsertOrUpdate('purchase_order_detail', $dataDetail);
        //更新总金额
        $data['money'] = $money;
        $data['po_id'] = $id;
        ToolModel::updateData(['id' => $id], ['money' => $money], 'purchase_order');
        $data['list'] = $dataDetail;
        //生成销售单 有发运单号的 自动类型
        if (empty($param['id']) && $data['type'] == 1) {
            $sellRes = SellService::create($data);
            if ($sellRes['code'] != 1) {
                return returnArr(500, '全部失败,生成销项单错误!' . $sellRes['msg']);
            }
            //生成入库单 如果不是配送计划就生成
            if (!empty($param['warehouseInput'])) {
                $warRes = WarehousecountryService::create($data);
                if ($warRes['code'] != 1) {
                    return returnArr(500, '全部失败,生国家仓入库单错误!' . $warRes['msg']);
                }
            }

        }
        //生成入库单 手动类型
        if (empty($param['id']) && $data['type'] == 2) {
            $data['bs_code'] = 'CG' . $data['po_id'];
            $warRes = WarehousecountryService::create($data);
            if ($warRes['code'] != 1) {
                return returnArr(500, '全部失败,生国家仓入库单错误!' . $warRes['msg']);
            }
        }
        if ($param['id']) {
            return returnArr(1, '成功');
        } else {
            return returnArr(1, '成功', ['url' => '#/Purchasemanage/index']);
        }
    }
    static public function detail($param)
    {
        $result[] = [];
        $detail = [];
        if (!empty($param['id'])) {
            $result = ToolModel::select('purchase_order', ['id' => $param['id']]);
            $detail = ToolModel::select('purchase_order_detail', ['po_id' => $param['id']]);
            $result = self::getListHandle($result);
        }
        $supplier=ToolModel::select('base_company',['type'=>['in',[5]]],'company_name','','id');
        $countryWarehouse = ToolModel::select('base_warehouse', ['type' => ['in', [2]]], 'warehouse_name', '', 'id');
        $myCompany = ToolModel::select('base_company', ['type' => ['in', [1, 3]]], 'company_name', '', 'id');
        $lsCompany = ToolModel::select('base_company', ['type' => ['in', [2,3]]], 'company_name', '', 'id');
        return returnArr(1, '', ['result' => $result[0],
            'supplier'=>$supplier,
            'detail' => $detail, 'lsCompany' => $lsCompany, 'myCompany' => $myCompany, 'countryWarehouse' => $countryWarehouse]);
    }

    static public function getList($param)
    {
/*       $id=ToolModel::dbInsertOrUpdate('warehouse_country_cost',[['codel'=>1,'sku'=>4,'receipt_warehouse_id'=>1]]);
       $id=ToolModel::insertData([['code'=>1,'sku'=>4],['sku'=>4,'code'=>2],['code'=>3,'sku'=>3]],'warehouse_country_cost');
        return returnArr(1,$id);*/
        if (empty($param['down'])) {
            $titles = [];
        } else {
            $titles = [
                'code' => '采购单号',
                'purchase_company_str' => '采购公司',
                'supplier_company_str' => '供应商',
                'receipt_warehouse_str' => '收货仓库',
                'arrival_date' => '预计到仓时间',
                'type_str' => '类型',
                'sku_num' => 'sku',
                'money' => '总金额',
                'ctime' => '创建时间'
            ];
        }
        return PurchasemanageModel::getList($param, $titles, "\app\index\service\PurchasemanageService::getListHandle");
    }

    static public function getListHandle($data)
    {
        $company = ConfigBase::getCompanyAll();
        $warehouse = ConfigBase::getWarehouseAll();
        $skuNum = PurchasemanageModel::getSKuNum(array_column($data, 'id'));
        $companyAddr = ToolModel::select('base_company', ['id' => ['in', array_column($data, 'supplier_company_id')]], 'address', '', 'id');
        foreach ($data as &$v) {
            $v['supplier_company_str'] = $company[$v['supplier_company_id']];
            $v['purchase_company_str'] = $company[$v['purchase_company_id']];
            $v['receipt_warehouse_str'] = $warehouse[$v['receipt_warehouse_id']] ?? '';
            $v['ship_warehouse_str'] = $warehouse[$v['ship_warehouse_id']] ?? '';
            $v['type_str'] = self::$typeStr[$v['type']];
            $v['sku_num'] = $skuNum[$v['id']];
            $v['company_addr'] = $companyAddr[$v['supplier_company_id']];
        }
        return $data;
    }

    /**
     *根据发运单号自动生成采购单并转换主体
     *  code传发运单号 有头程签收数量时触发
     * @param $param
     * @param $type =1有接口时自动触发,type=2测试用
     * @return array
     * @author xiejunyu
     */
    static public function createAuto($param,$type=1)
    {

        //海外公司 YUJISO香港有限公司 10001
        //收货仓(只能国家仓)
        //收货零售公司(非贸易)  收货贸易公司(非零售所有公司)
        //香港10001 (香港仓)向国内深圳市亚创电子商务有限公司(7号仓发货仓)  10002(单价加销项比例)采购  贸易()向香港采购   零售向贸易采购(取国家仓)

        $plan = ToolModel::findByAttributes("ship_plan", ['code' => $param['code']]);
        $purchaseOrder = ToolModel::findByAttributes('purchase_order', ['bs_code' => $plan['code']]);
        if ($purchaseOrder) {
            return returnArr(2, "发运单号{$plan['code']}已生成过采购单");
        }
        if ($plan['ybr_status'] != 1) {
            return returnArr(500, "发运单号{$plan['code']}还没有上传标记配送");
        }
        if (empty($plan['trading_company'])) {
            return returnArr(500, "发运单号{$plan['code']}贸易公司不能为空");
        }
        $planDetail = ToolModel::select("ship_plan_detail",
            ['ybr_status' => 1, 'ship_plan_id' => $plan['id']],
            'sku,sku_name,real_quantity as quantity,unit_price'
        );
        if (empty($planDetail)) {
            return returnArr(500, "发运单号{$plan['code']}不存在标记配送的明细");
        }
        $list = [];
        foreach ($planDetail as $v) {
            $temp = [];
            $temp['sku'] = $v['sku'];
            $temp['sku_name'] = $v['sku_name'];
            if (empty($list[$v['sku']])) {
                $temp['quantity'] = $v['quantity'];
            } else {
                $temp['quantity'] = $list[$v['sku']]['quantity'] + $v['quantity'];
            }
            $temp['sku'] = $v['sku'];
            $temp['unit_price'] = $v['unit_price'];
            $list[$v['sku']] = $temp;
        }
        ToolModel::startTrans();
        try {
            $po = [];
            $data = [];
            //香港向国内采购
            $data['id'] = '';
            $data['purchase_company_id'] = $plan['overseas_company'];
            $data['supplier_company_id'] = $plan['company_id_out'];
            $data['arrival_date'] = TIME;
            $data['bs_code'] = $plan['code'];
            $data['type'] = 1;//2手动1自动
            $data['status'] = 10;//10未完成20完成
            $data['ctime'] = TIME;
            $data['user'] = $plan['user'];
            $data['list'] = $list;//采购明细
            $sale_proportion = ToolModel::getValue('base_company', ['id' => $data['supplier_company_id']], 'sale_proportion');
            if (!preg_match("/(^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$)|(^[1-9]\d*$)/", $sale_proportion)) {
                $msg[] = "销项加成比例{$sale_proportion}不正确!";
            }
            foreach ($data['list'] as &$v1) {
                $v1['unit_price'] = bcmul(bcadd(1, $sale_proportion, 5), $v1['unit_price'], 5);
            }
            if($type==2){
                //测试用
                $sql="INSERT INTO ship_plan_cost(`code`,sku,head,`end`) SELECT a.code,b.sku,10 AS head,10 AS `end` FROM ship_plan a
 INNER JOIN  ship_plan_detail b
 ON a.`id`=b.`ship_plan_id` 
 WHERE a.code='{$param['code']}' group by b.sku";
                ToolModel::execute($sql);
                $sql="INSERT INTO ship_plan_receive(`code`,shop_id,case_number,sku,quantity) SELECT a.code,b.shop_id,b.id,b.sku,b.real_quantity FROM ship_plan a
     INNER JOIN  ship_plan_detail b
     ON a.`id`=b.`ship_plan_id` 
     WHERE a.code='{$param['code']}'";
                ToolModel::execute($sql);
                $sql="INSERT INTO ship_plan_send(`code`,shop_id,box_number,sku,quantity,`date`) SELECT a.code,b.shop_id,b.id,b.sku,b.real_quantity,b.ctime FROM ship_plan a
     INNER JOIN  ship_plan_detail b
     ON a.`id`=b.`ship_plan_id` 
     WHERE a.code='{$param['code']}'";
                ToolModel::execute($sql);
            }
            $po[] = $data;

            //国家贸易向香港采购
            $data['purchase_company_id'] = $plan['trading_company'];
            $data['supplier_company_id'] = $plan['overseas_company'];
            $sale_proportion = ToolModel::getValue('base_company', ['id' => $data['supplier_company_id']], 'sale_proportion');
            if (!preg_match("/(^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$)|(^[1-9]\d*$)/", $sale_proportion)) {
                $msg[] = "销项加成比例{$sale_proportion}不正确!";
            }
            $data2=ToolModel::copyArr($data);
            foreach ($data2['list'] as &$v2) {
                $v2['unit_price'] = bcmul(bcadd(1, $sale_proportion, 5), $v2['unit_price'], 5);
            }
            $po[] = $data2;

            //零售向贸易采购
            if ($plan['retail_company'] != $plan['trading_company']) {
                $data2['purchase_company_id'] = $plan['retail_company'];
                $data2['supplier_company_id'] = $plan['trading_company'];
                $sale_proportion = ToolModel::getValue('base_company', ['id' => $data2['supplier_company_id']], 'sale_proportion');
                if (!preg_match("/(^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$)|(^[1-9]\d*$)/", $sale_proportion)) {
                    $msg[] = "销项加成比例{$sale_proportion}不正确!";
                }
                $data3=ToolModel::copyArr($data2);
                foreach ($data3['list'] as &$v3) {
                    $v3['unit_price'] = bcmul(bcadd(1, $sale_proportion, 5), $v3['unit_price'], 5);
                }
                $po[] = $data3;
            }
            if (!empty($msg)) {
                return returnArr(500, $msg);
            }
            $ok = 1;
            $poCount = count($po) - 1;
            foreach ($po as $k => $v) {
                if ($poCount == $k) {
                    $v['warehouseInput'] = 1;
                }
                $poRes = self::create($v);
                if ($poRes['code'] != 1) {
                    $ok = 0;
                }
            }
            if ($ok == 1) {
                ToolModel::commit();
                return returnArr(1,'成功');
            } else {
                ToolModel::rollback();
                return returnArr(500,'失败');
            }
        } catch (\Exception $e) {
            ToolModel::rollback();
            trace($e->getMessage(), 'error');
            return returnArr(600, '失败' . $e->getMessage());
        }
    }

    /**
     *配送计划审核通过时生成采销
     * 不需要生成入库单
     * @param $param
     * @return array
     * @author xiejunyu
     */
    static public function createPoByDp($param)
    {
        $plan = ToolModel::findByAttributes("distribution_plan", ['id' => $param['id']]);
        if ($plan['type'] == 1) {
            return returnArr(1);
        }
        $purchaseOrder = ToolModel::findByAttributes('purchase_order', ['bs_code' => $plan['code']]);
        if ($purchaseOrder) {
            return returnArr(500, "配送单号{$plan['code']}已生成过采购单");
        }
        if ($plan['status'] != 2) {
            return returnArr(500, "配送单号{$plan['code']}未审核通过");
        }
        $planDetail = ToolModel::select("distribution_plan_detail",
            ['status' => 1, 'distribution_plan_id' => $plan['id']],
            'sku,sku_name,quantity,price as unit_price'
        );
        if (empty($planDetail)) {
            return returnArr(500, "发运单号{$plan['code']}不存在标记配送的明细");
        }
        $data = [];
        $data['id'] = '';
        $data['purchase_company_id'] = $plan['recieve_company'];
        $data['supplier_company_id'] = $plan['company_id_out'];
        $data['arrival_date'] = TIME;
        $data['bs_code'] = $plan['code'];
        $data['type'] = 1;//2手动1自动
        $data['status'] = 20;//10未完成20完成
        $data['ctime'] = TIME;
        $data['user'] = $plan['operator'];
        $data['list'] = $planDetail;//采购明细
        $data['dy'] = 1;//配送计划标识
        $sale_proportion = ToolModel::getValue('base_company', ['id' => $data['supplier_company_id']], 'sale_proportion');
        if (!preg_match("/(^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$)|(^[1-9]\d*$)/", $sale_proportion)) {
            $msg[] = "销项加成比例{$sale_proportion}不正确!";
        }
        foreach ($data['list'] as &$v1) {
            $v1['unit_price'] = bcmul(bcadd(1, $sale_proportion, 5), $v1['unit_price'], 5);
        }
        $poRes = self::create($data);
        return $poRes;
    }
}